﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Framework
{
    public class DragTrigger : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
    {
        private List<UIClickListener> _listCsharpBeginListener = new List<UIClickListener>();
        private List<UIClickListener> _listCsharpDragListener = new List<UIClickListener>();
        private List<UIClickListener> _listCsharpEndListener = new List<UIClickListener>();
        
        
        public static DragTrigger Get(Transform transform)
        {
            DragTrigger trigger = transform.GetComponent<DragTrigger>();
            if (trigger == null)
            {
                trigger = transform.gameObject.AddComponent<DragTrigger>();
            }
            return trigger;
        }
        
        void OnDestroy()
        {
            this._listCsharpBeginListener = null;
            this._listCsharpDragListener = null;
            this._listCsharpEndListener = null;
        }

        public void AddBeginListener(Action<object[]> callback, params object[] args)
        {
            int index = FindCSharpListener(_listCsharpBeginListener, callback);
            if (index == -1)
            {
                UIClickListener clickListener = new UIClickListener(callback, args);
                _listCsharpBeginListener.Add(clickListener);
            }
        }

        public void RemoveBeginListener(Action<object[]> callback)
        {
            int index = FindCSharpListener(_listCsharpBeginListener, callback);
            if (index != -1)
            {
                _listCsharpBeginListener.RemoveAt(index);
            }
        }

        public void AddDragListener(Action<object[]> callback, params object[] args)
        {
            int index = FindCSharpListener(_listCsharpDragListener, callback);
            if (index == -1)
            {
                UIClickListener clickListener = new UIClickListener(callback, args);
                _listCsharpDragListener.Add(clickListener);
            }
        }

        public void RemoveDragListener(Action<object[]> callback)
        {
            int index = FindCSharpListener(_listCsharpDragListener, callback);
            if (index != -1)
            {
                _listCsharpDragListener.RemoveAt(index);
            }
        }

        public void AddEndListener(Action<object[]> callback, params object[] args)
        {
            int index = FindCSharpListener(_listCsharpEndListener, callback);
            if (index == -1)
            {
                UIClickListener clickListener = new UIClickListener(callback, args);
                _listCsharpEndListener.Add(clickListener);
            }
        }

        public void RemoveEndListener(Action<object[]> callback)
        {
            int index = FindCSharpListener(_listCsharpEndListener, callback);
            if (index != -1)
            {
                _listCsharpEndListener.RemoveAt(index);
            }
        }
        
        public void OnPointerDown(PointerEventData eventData)
        {
            OnBeginDrag(eventData);
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            OnEndDrag(eventData);
        }

        public void OnBeginDrag(PointerEventData eventData)
        {
            int count = _listCsharpBeginListener.Count;
            for (int i = 0; i < count; ++i)
            {
                UIClickListener clickListener = _listCsharpBeginListener[i];
                clickListener.Invoke(eventData);
            }
        }
        
        public void OnDrag(PointerEventData eventData)
        {
            int count = _listCsharpDragListener.Count;
            for (int i = 0; i < count; ++i)
            {
                UIClickListener clickListener = _listCsharpDragListener[i];
                clickListener.Invoke(eventData);
            }
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            int count = _listCsharpEndListener.Count;
            for (int i = 0; i < count; ++i)
            {
                UIClickListener clickListener = _listCsharpEndListener[i];
                clickListener.Invoke(eventData);
            }
        }

        private int FindCSharpListener(List<UIClickListener> listListener, Action<object[]> callback)
        {
            int count = listListener.Count;
            for (int i = 0; i < count; ++i)
            {
                UIClickListener clickListener = listListener[i];
                if (clickListener.Equals(callback))
                {
                    return i;
                }
            }
            return -1;
        }
    }
}